package com.ruiyian.bridge.dataAnalysis.service.Impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ruiyian.bridge.dataAnalysis.service.DataAnalysisService;
import com.ruiyian.bridge.info.mapper.*;
import com.ruiyian.bridge.project.domain.vo.DataAnalysisDto;
import com.ruiyian.bridge.project.domain.vo.DataAnalysisVo;
import com.ruiyian.bridge.project.enums.DeviceTypeEnum;
import com.ruiyian.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * @author chong
 * @email 673426164@qq.com
 * @create 2021/10/27
 * Desc: 数据分析
 */
@Slf4j
@Service
public class DataAnalysisServiceImpl implements DataAnalysisService {
    @Autowired
    private DistanceInfoMapper distanceInfoMapper;
    @Autowired
    private TemperatureMapper temperatureMapper;

    @Autowired
    private VibrationAccelerationMapper vibrationAccelerationMapper;
    @Autowired
    private VehicleWeightMapper vehicleWeightMapper;
    @Autowired
    private Mmh2oInfoMapper mmh2oInfoMapper;
    @Autowired
    private DipmonitorInfoMapper dipmonitorInfoMapper;

    /**
     * 相关性分析
     * @param dto
     * @return
     */
    @Override
    public Map<String, Object> getCorrelation(DataAnalysisDto dto) {
        Map<String,Object> returnData = Maps.newHashMap();
        List<List<Object>> source = Lists.newArrayList();
        List<DataAnalysisVo> xDataList = null;
        List<DataAnalysisVo> yDataList = null;
        // 影响因素 x轴
        if(dto.getShebeiType2()== DeviceTypeEnum.DISTANCE.getType()){
            // 激光
            xDataList = distanceInfoMapper.queryDisByDateSenNoCorr(new DataAnalysisDto(dto.getStartTime(), dto.getEndTime(),dto.getSensorNo2()));
        }else if(dto.getShebeiType2()==DeviceTypeEnum.VIBRATIONACCELERATION.getType()){
            // 加速度
            xDataList = vibrationAccelerationMapper.queryDateSenNoCorr(new DataAnalysisDto(dto.getStartTime(), dto.getEndTime(),dto.getSensorNo2()));
        } else if(dto.getShebeiType2()==DeviceTypeEnum.TEMPERATURE.getType()){
            // 温度
            xDataList =temperatureMapper.queryTempByDateSenNo(new DataAnalysisDto(dto.getStartTime(), dto.getEndTime(),dto.getSensorNo2()));
        }else if(dto.getShebeiType2()==DeviceTypeEnum.WEIGHT.getType()){
            // 车重
            xDataList =vehicleWeightMapper.queryDateSenNoCorr(new DataAnalysisDto(dto.getStartTime(), dto.getEndTime(),dto.getSensorNo2()));
        }else if(dto.getShebeiType2()==DeviceTypeEnum.MMH2O.getType()){
            // 静力
            xDataList =mmh2oInfoMapper.queryByDateSenNoCorr(new DataAnalysisDto(dto.getStartTime(), dto.getEndTime(),dto.getSensorNo2()));
        }else if(dto.getShebeiType2()==DeviceTypeEnum.DIPMONITOR.getType()){
            // 倾角
            xDataList =dipmonitorInfoMapper.queryByDateSenNoCorr(new DataAnalysisDto(dto.getStartTime(), dto.getEndTime(),dto.getSensorNo2()));
        }
        // 检测量 y轴
        if(dto.getShebeiType1()==DeviceTypeEnum.DISTANCE.getType()){
            // 激光
            yDataList = distanceInfoMapper.queryDisByDateSenNoCorr(dto);
        }else if(dto.getShebeiType1()==DeviceTypeEnum.VIBRATIONACCELERATION.getType()){
            // 加速度
            yDataList = vibrationAccelerationMapper.queryDateSenNoCorr(dto);
        } else if(dto.getShebeiType1()==DeviceTypeEnum.TEMPERATURE.getType()){
            // 温度
            yDataList =temperatureMapper.queryTempByDateSenNo(dto);
        }else if(dto.getShebeiType1()==DeviceTypeEnum.WEIGHT.getType()){
            // 车重
            yDataList =vehicleWeightMapper.queryDateSenNoCorr(dto);
        }else if(dto.getShebeiType1()==DeviceTypeEnum.MMH2O.getType()){
            // 静力
            yDataList =mmh2oInfoMapper.queryByDateSenNoCorr(dto);
        } else if(dto.getShebeiType1()==DeviceTypeEnum.DIPMONITOR.getType()){
            // 倾角
            yDataList =dipmonitorInfoMapper.queryByDateSenNoCorr(dto);
        }
        // 数据处理构建
        if(null!=xDataList && xDataList.size()>0){
            for(DataAnalysisVo t: xDataList){
                List<Object> list = Lists.newArrayList();
                try {
                    // 反射根据key获取对应监测项值
                    Field field = t.getClass().getDeclaredField(dto.getItem2());
                    field.setAccessible(true);
                    String s = (String) field.get(t);
                    list.add(s);
                } catch (Exception e) {
                    log.error("获取数据失败");
                }
                List<DataAnalysisVo> collect = yDataList.stream().filter(f -> f.getCreatTime().equals(t.getCreatTime())).collect(Collectors.toList());
                if(collect.size()>0){
                    try {
                        // 反射根据key获取对应监测项值
                        DataAnalysisVo dataAnalysisVo = collect.get(0);
                        Field field = dataAnalysisVo.getClass().getDeclaredField(dto.getItem1());
                        field.setAccessible(true);
                        String s = (String) field.get(dataAnalysisVo);
                        list.add(s);
                    } catch (Exception e) {
                        log.error("获取数据失败");
                    }
                }else{
                    list.add(0);
                }
                source.add(list);
            }
        }
        returnData.put("source",source);
        return returnData;
    }

    /**
     * 同期对比
     * @param dto
     * @return
     */
    @Override
    public Map<String, Object> getSanmePeriodList(DataAnalysisDto dto) {
        Map<String,Object> retrurnData = Maps.newHashMap();
        List<Map<String,Object>> xAxis = Lists.newArrayList();
        List<Map<String,Object>> series = Lists.newArrayList();
        List<DataAnalysisVo> distanceInfos = null; //上
        List<DataAnalysisVo> distanceInfoss = null; //下
        String startTime = dto.getStartTime();
        String endTime = dto.getEndTime();
        if(dto.getShebeiType1()==DeviceTypeEnum.DISTANCE.getType()) {
            // 激光
            distanceInfos = distanceInfoMapper.queryDisByDateType(dto);
            dto.setStartTime(dto.getPkstartTime());
            dto.setEndTime(dto.getPkendTime());
            distanceInfoss = distanceInfoMapper.queryDisByDateType(dto);
        }else if(dto.getShebeiType1()==DeviceTypeEnum.VIBRATIONACCELERATION.getType()){
            // 加速度
            distanceInfos = vibrationAccelerationMapper.queryByDateType(dto);
            dto.setStartTime(dto.getPkstartTime());
            dto.setEndTime(dto.getPkendTime());
            distanceInfoss = vibrationAccelerationMapper.queryByDateType(dto);
        } else if(dto.getShebeiType1()==DeviceTypeEnum.TEMPERATURE.getType()) {
            // 温度
            distanceInfos = temperatureMapper.querySameTempByDateType(dto);
            dto.setStartTime(dto.getPkstartTime());
            dto.setEndTime(dto.getPkendTime());
            distanceInfoss = temperatureMapper.querySameTempByDateType(dto);
        } else if(dto.getShebeiType1()==DeviceTypeEnum.WEIGHT.getType()) {
            // 车重
            distanceInfos = vehicleWeightMapper.queryByDateType(dto);
            dto.setStartTime(dto.getPkstartTime());
            dto.setEndTime(dto.getPkendTime());
            distanceInfoss = vehicleWeightMapper.queryByDateType(dto);
        }else if(dto.getShebeiType1()==DeviceTypeEnum.MMH2O.getType()) {
            // 静力
            distanceInfos = mmh2oInfoMapper.queryDisByDateType(dto);
            dto.setStartTime(dto.getPkstartTime());
            dto.setEndTime(dto.getPkendTime());
            distanceInfoss = mmh2oInfoMapper.queryDisByDateType(dto);
        }else if(dto.getShebeiType1()==DeviceTypeEnum.DIPMONITOR.getType()) {
            // 倾角
            distanceInfos = dipmonitorInfoMapper.queryByDateType(dto);
            dto.setStartTime(dto.getPkstartTime());
            dto.setEndTime(dto.getPkendTime());
            distanceInfoss = dipmonitorInfoMapper.queryByDateType(dto);
        }
        // 数据处理
        if(distanceInfos.size()>0){
            List<String> date = Lists.newArrayList();
            List<String> value = Lists.newArrayList();
            distanceInfos.stream().peek(d->{
                date.add(d.getCreatTime());
                try {
                    // 反射根据key获取对应监测项值
                    Field field = d.getClass().getDeclaredField(dto.getItem1());
                    field.setAccessible(true);
                    String s = (String) field.get(d);
                    value.add(s);
                } catch (Exception e) {
                    log.error("获取数据失败");
                }
            }).collect(Collectors.toList());
            Map<String,Object> map = Maps.newHashMap();
            map.put("data",date);
            xAxis.add(map);
            map = Maps.newHashMap();
            map.put("data",value);
            map.put("type","line");
            map.put("showSymbol",false);
            map.put("name",startTime+"-"+endTime);
            series.add(map);
        }
        if(distanceInfoss.size()>0){
            List<String> date = Lists.newArrayList();
            List<String> value = Lists.newArrayList();
            distanceInfoss.stream().peek(d->{
                date.add(d.getCreatTime());
                try {
                    // 反射根据key获取对应监测项值
                    Field field = d.getClass().getDeclaredField(dto.getItem1());
                    field.setAccessible(true);
                    String s = (String) field.get(d);
                    value.add(s);
                } catch (Exception e) {
                    log.error("获取数据失败");
                }
            }).collect(Collectors.toList());
            Map<String,Object> map = Maps.newHashMap();
            map.put("data",date);
            map.put("gridIndex",1);
            xAxis.add(map);
            map = Maps.newHashMap();
            map.put("data",value);
            map.put("xAxisIndex",1);
            map.put("yAxisIndex",1);
            map.put("type","line");
            map.put("showSymbol",false);
            map.put("name",dto.getPkstartTime()+"-"+dto.getPkendTime());
            series.add(map);
        }
        retrurnData.put("xAxis",xAxis);
        retrurnData.put("series",series);
        return retrurnData;
    }

    /**
     * 频谱分析
     * @param dto
     * @return
     */
    @Override
    public Map<String, Object> getSpectrumList(DataAnalysisDto dto) {
        Map<String,Object> returnMap = Maps.newHashMap();
        TreeSet<String> xData = new TreeSet<>();
        List<String> legendData = new ArrayList<>();
        List<Map<String,Object>> series = new ArrayList<>();
        List<DataAnalysisVo> dataAnalysisVos = vibrationAccelerationMapper.queryVibList(dto);
        if(dataAnalysisVos.size()>0){
            dataAnalysisVos.stream().peek(p->{
                xData.add(p.getFrequency());
            }).collect(Collectors.toList());
            Map<String, List<DataAnalysisVo>> collect = dataAnalysisVos.stream().collect(Collectors.groupingBy(DataAnalysisVo::getSensorNo));
            for(Map.Entry<String, List<DataAnalysisVo>> map: collect.entrySet()){
                Map<String,Object> serMap = Maps.newHashMap();
                legendData.add(map.getKey());
                List<DataAnalysisVo> value = map.getValue();
                List<String> yData = Lists.newArrayList();
                for(String str: xData){
                    List<DataAnalysisVo> dataList = value.stream().filter(f -> StringUtils.isNoneBlank(f.getFrequency()) && f.getFrequency().equals(str)).collect(Collectors.toList());
                    if(dataList.size()>0){
                        yData.add(dataList.get(0).getAcceleration());
                    }else {
                        yData.add("0");
                    }
                }
                serMap.put("name",map.getKey());
                serMap.put("type","line");
                serMap.put("data",yData);
                series.add(serMap);
            }
        }
        returnMap.put("legend",legendData);
        returnMap.put("category",xData);
        returnMap.put("series",series);
        return returnMap;
    }

    /**
     * 同步分析
     * @param dto
     * @return
     */
    @Override
    public Map<String, Object> getSynchronous(DataAnalysisDto dto) {
        if(dto.getType()==1){
            String startTime = dto.getStartTime();
            String nextDate = DateUtils.getNextDate(1,DateUtils.dateTime("yyyy-MM-dd HH:mm",startTime) , -10, new SimpleDateFormat("yyyy-MM-dd HH:mm"));
            dto.setStartTime(nextDate);
            dto.setEndTime(startTime);
        }
        Map<String,Object> returnData = Maps.newHashMap();
        List<String> xAxis = Lists.newArrayList();
        List<Map<String,Object>> series = Lists.newArrayList();
        List<String> data = Lists.newArrayList();
        List<DataAnalysisVo> distanceInfos = null;
        if(dto.getShebeiType1()==DeviceTypeEnum.DISTANCE.getType()) {
            // 激光
            distanceInfos = distanceInfoMapper.queryDisByDateSenNo(dto);
        }else if(dto.getShebeiType1()==DeviceTypeEnum.VIBRATIONACCELERATION.getType()){
            // 加速度
            distanceInfos =  vibrationAccelerationMapper.queryDisByDateSenNo(dto);
        } else if(dto.getShebeiType1()==DeviceTypeEnum.TEMPERATURE.getType()) {
            // 温度
            distanceInfos = temperatureMapper.queryTempByDateGroupSenNo(dto);
        }else if(dto.getShebeiType1()==DeviceTypeEnum.WEIGHT.getType()) {
            // 车重
            distanceInfos = vehicleWeightMapper.queryDisByDateSenNo(dto);
        }else if(dto.getShebeiType1()==DeviceTypeEnum.MMH2O.getType()) {
            // 静力
            distanceInfos = mmh2oInfoMapper.queryDisByDateSenNo(dto);
        }else if(dto.getShebeiType1()==DeviceTypeEnum.DIPMONITOR.getType()) {
            // 倾角
            distanceInfos = dipmonitorInfoMapper.queryDisByDateSenNo(dto);
        }
        if(distanceInfos!=null && distanceInfos.size()>0){
            if (distanceInfos.size() > 0) {
                distanceInfos.stream().peek(f->{
                    xAxis.add(f.getMacAddr()+"-"+f.getAddr());
                    try {
                        // 反射根据key获取对应监测项值
                        Field field = f.getClass().getDeclaredField(dto.getItem1());
                        field.setAccessible(true);
                        String s = (String) field.get(f);
                        data.add(s);
                    } catch (Exception e) {
                        log.error("获取数据失败");
                    }
                }).collect(Collectors.toList());
                Map<String,Object> map = Maps.newHashMap();
                map.put("data",data);
                series.add(map);
            }
        }
        returnData.put("series",series);
        returnData.put("category",xAxis);
        return  returnData;
    }

    /**
     * 数据查看
     * @param dto
     * @return
     */
    @Override
    public Map<String, Object> lookData(DataAnalysisDto dto) {
        Map<String,Object> returnData = Maps.newHashMap();
        List<String> xAxis = Lists.newArrayList();
        List<Map<String,Object>> series = Lists.newArrayList();
        List<DataAnalysisVo> distanceInfos = null;
        if(dto.getShebeiType1()== DeviceTypeEnum.DISTANCE.getType()){
            // 激光
            distanceInfos = distanceInfoMapper.queryDisByDateType(dto);
        }else if(dto.getShebeiType1()== DeviceTypeEnum.VIBRATIONACCELERATION.getType()){
            // 加速度
            distanceInfos =  vibrationAccelerationMapper.queryByDateType(dto);
        }else if(dto.getShebeiType1()== DeviceTypeEnum.TEMPERATURE.getType()){
            // 温度
            distanceInfos =  temperatureMapper.querySameTempByDateType(dto);
        }else if(dto.getShebeiType1()== DeviceTypeEnum.WEIGHT.getType()){
            // 车重
            distanceInfos =  vehicleWeightMapper.queryByDateType(dto);

        }else if(dto.getShebeiType1()== DeviceTypeEnum.MMH2O.getType()){
            // 静力
            distanceInfos =  mmh2oInfoMapper.queryDisByDateType(dto);
        }else if(dto.getShebeiType1()== DeviceTypeEnum.DIPMONITOR.getType()){
            // 倾角
            distanceInfos =  dipmonitorInfoMapper.queryByDateType(dto);
        }
        List<String> value = Lists.newArrayList();
        if(distanceInfos.size()>0){
            distanceInfos.stream().peek(d->{
                xAxis.add(d.getCreatTime());
                try {
                    // 反射根据key获取对应监测项值
                    Field field = d.getClass().getDeclaredField(dto.getItem1());
                    field.setAccessible(true);
                    String s = (String) field.get(d);
                    value.add(s);
                } catch (Exception e) {
                    log.error("获取数据失败");
                }
            }).collect(Collectors.toList());
            Map<String,Object> map = Maps.newHashMap();
            map.put("data",value);
            map.put("type","line");
            map.put("showSymbol",false);
            series.add(map);
        }
        returnData.put("category",xAxis);
        returnData.put("series",series);
        return returnData;
    }
}
